package com.wellsoft.mobileoa.utils.action;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract.CommonDataKinds.Event;

import com.wellsoft.mobileoa.utils.BaseAction;
import com.wellsoft.mobileoa.utils.BaseActivity;
import com.wellsoft.mobileoa.utils.BaseView;
import com.wellsoft.mobileoa.utils.SystemConfig;
import com.wellsoft.mobileoa.wsmodel.WSOA_Action;
import com.wellsoft.mobileoa.wsmodel.WSOA_Appointment;
import com.wellsoft.mobileoa.wsmodel.WSOA_AppointmentProcess_Request;
import com.wellsoft.mobileoa.wsmodel.WSOA_AppointmentProcess_Response;
import com.wellsoft.mobileoa.wsmodel.WSOA_PostField;
import com.wmobile.utils.BaseObject;
import com.wmobile.utils.PopConfirmDialog;
import com.wmobile.utils.ServiceResponse;

public class SyncAppointment extends BaseAction {
	List<Appointment> scheduleList = new ArrayList<Appointment>();

	public static SimpleDateFormat dateSdf = new SimpleDateFormat("yyyy-MM-dd");

	public static SimpleDateFormat timeSdf = new SimpleDateFormat("HH:mm");

	public static SimpleDateFormat datetimeSdf = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm");

	public SyncAppointment(WSOA_Action action, BaseView baseView) {
		this.action = action;
		this.baseView = baseView;
	}

	@Override
	public ServiceResponse excuteAction() {
		if(!isMainThread){
			if (action.getPageConfirm() != null
					&& !SystemConfig.stringIsNullOrEmpty(action.getPageConfirm()
							.getMessage())) {
				PopConfirmDialog confirmDialog = new PopConfirmDialog(baseView.getBaseActivity(),
						action.getPageConfirm().getMessage());
				if (confirmDialog.showDialog() != PopConfirmDialog.DialogResultOK) {
					return new ServiceResponse(false);
				}
			}
		}
		List<String> funcType = getFuncType(action.getFuncType());
		List<WSOA_Appointment> wsAppointmentes = getAppointment();

		WSOA_AppointmentProcess_Request request = new WSOA_AppointmentProcess_Request();
		request.setProcessType(funcType.get(3));
		request.setDownloadUrl(funcType.get(1));
		request.setUploadUrl(funcType.get(2));
		request.setUser(SystemConfig.getUserName());
		request.setAppointment(wsAppointmentes);
		request.setCookies(SystemConfig.getCookies());

		Map<String, BaseObject> httpRequests = new HashMap<String, BaseObject>();

		httpRequests.put("request", request);
		ServiceResponse httpGetResponse = null;
		if (isMainThread) {
			httpGetResponse = SystemConfig.getService()
					.CallserviceOnMainThread(httpRequests,
							"WSOA_AppointmentProcess",
							WSOA_AppointmentProcess_Response.class);
		} else {
			httpGetResponse = SystemConfig.getService().Callservice(
					httpRequests, "WSOA_AppointmentProcess",
					WSOA_AppointmentProcess_Response.class);
		}
		if (!httpGetResponse.getExeFlag()) {
			return httpGetResponse;
		}
		WSOA_AppointmentProcess_Response response = (WSOA_AppointmentProcess_Response) httpGetResponse
				.getResponseData();
		if (response.getExeFlag() == 2) {
			if (SystemConfig.reLogin()) {
				return excuteAction();
			} else {
				BaseActivity.returnLoginActivity();
				return new ServiceResponse(false);
			}
		}
		if (response.getExeFlag() == 0) {
//			baseView.getBaseActivity().showMessage(response.getMessage());
			return new ServiceResponse(false, response.getMessage());
		}

		if (request.getProcessType().equals("down")
				|| request.getProcessType().equals("updown")) {
			if (response.getAppointment() != null) {
				try {
					setAppointment(response.getAppointment());
				} catch (RemoteException e) {
					e.printStackTrace();
				} catch (OperationApplicationException e) {
					e.printStackTrace();
				} catch (ParseException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		if(!isMainThread){
			baseView.getBaseActivity().showMessage("同步成功");
		}
		return new ServiceResponse(true, "同步成功");
	}

	public List<WSOA_Appointment> getAppointment() {
		String calanderReminderURL = "content://com.android.calendar/reminders";

		List<WSOA_Appointment> wsAppointments = new ArrayList<WSOA_Appointment>();

		String[] projection = new String[] { "_id", "dtstart", "dtend",
				"title", "description", "hasAlarm", "eventLocation" };
		Uri calendarEvents = Uri.parse("content://com.android.calendar/events");
		ContentResolver resolver = baseView.getBaseActivity()
				.getContentResolver();

		Cursor managedCursor = resolver.query(calendarEvents, projection, null,
				null, null);

		while (managedCursor.moveToNext()) {
			Appointment appointment = new Appointment();
			WSOA_Appointment wsAppointment = new WSOA_Appointment();
			List<WSOA_PostField> postFields = new ArrayList<WSOA_PostField>();
			WSOA_PostField field;
			List<String> values;

			Long recordID = managedCursor.getLong(managedCursor
					.getColumnIndex("_id"));
			appointment.setRecordId(recordID);

			long dtstart = managedCursor.getLong(managedCursor
					.getColumnIndex("dtstart"));
			Date startDate = new Date(dtstart);
			field = new WSOA_PostField();
			field.setFieldName("startdate");
			values = new ArrayList<String>();
			values.add(dateSdf.format(startDate));
			field.setFieldValues(values);
			postFields.add(field);

			field = new WSOA_PostField();
			field.setFieldName("starttime");
			values = new ArrayList<String>();
			values.add(timeSdf.format(startDate));
			field.setFieldValues(values);
			postFields.add(field);

			appointment.setStartdate(dateSdf.format(startDate));
			appointment.setStarttime(timeSdf.format(startDate));

			long dtend = managedCursor.getLong(managedCursor
					.getColumnIndex("dtend"));
			Date endDate = new Date(dtend);
			field = new WSOA_PostField();
			field.setFieldName("enddate");
			values = new ArrayList<String>();
			values.add(dateSdf.format(endDate));
			field.setFieldValues(values);
			postFields.add(field);

			field = new WSOA_PostField();
			field.setFieldName("endtime");
			values = new ArrayList<String>();
			values.add(timeSdf.format(endDate));
			field.setFieldValues(values);
			postFields.add(field);

			appointment.setEnddate(dateSdf.format(endDate));
			appointment.setEndtime(timeSdf.format(endDate));

			String title = managedCursor.getString(managedCursor
					.getColumnIndex("title"));
			field = new WSOA_PostField();
			field.setFieldName("subject");
			values = new ArrayList<String>();
			values.add(title);
			field.setFieldValues(values);
			postFields.add(field);

			appointment.setSubject(title);

			String note = managedCursor.getString(managedCursor
					.getColumnIndex("description"));
			field = new WSOA_PostField();
			field.setFieldName("taskcont");
			values = new ArrayList<String>();
			values.add(note);
			field.setFieldValues(values);
			postFields.add(field);

			appointment.setTaskcont(note);

			String hasAlarm = managedCursor.getString(managedCursor
					.getColumnIndex("hasAlarm"));
			field = new WSOA_PostField();
			field.setFieldName("alarms");
			values = new ArrayList<String>();
			values.add(hasAlarm);
			field.setFieldValues(values);
			postFields.add(field);

			appointment.setAlarms(hasAlarm);

			Cursor reminderCursor = resolver.query(
					Uri.parse(calanderReminderURL), new String[] { "event_id",
							"method", "minutes" }, "event_id=?",
					new String[] { String.valueOf(recordID) }, null);
			if (reminderCursor.getCount() > 0) {
				reminderCursor.moveToFirst();
				appointment.setAlarmtime(reminderCursor
						.getString(reminderCursor.getColumnIndex("minutes")));
			}
			reminderCursor.close();

			String location = managedCursor.getString(managedCursor
					.getColumnIndex("eventLocation"));
			field = new WSOA_PostField();
			field.setFieldName("location");
			values = new ArrayList<String>();
			values.add(location);
			field.setFieldValues(values);
			postFields.add(field);

			appointment.setLocation(location);

			wsAppointment.setFields(postFields);
			wsAppointments.add(wsAppointment);
			scheduleList.add(appointment);
		}
		managedCursor.close();
		return wsAppointments;
	}

	public void setAppointment(List<WSOA_Appointment> wsAppointmentes)
			throws RemoteException, OperationApplicationException,
			ParseException {
		String calanderURL = "content://com.android.calendar/calendars";
		String calanderEventURL = "content://com.android.calendar/events";
		String calanderReminderURL = "content://com.android.calendar/reminders";

		String calId = "";
		Cursor userCursor = baseView.getBaseActivity().getContentResolver()
				.query(Uri.parse(calanderURL), null, null, null, null);
		if (userCursor.getCount() > 0) {
			userCursor.moveToFirst();
			calId = userCursor.getString(userCursor.getColumnIndex("_id"));

		}
		userCursor.close();

		for (WSOA_Appointment wsAppointment : wsAppointmentes) {
			Appointment appointment = new Appointment();

			for (WSOA_PostField field : wsAppointment.getFields()) {
				if (SystemConfig.stringIsNullOrEmpty(field.getFieldName())
						|| field.getFieldValues() == null
						|| field.getFieldValues().size() == 0)
					continue;

				if (field.getFieldName().toLowerCase().equals("subject")) {
					appointment.setSubject(field.getFieldValues().get(0));
				} else if (field.getFieldName().toLowerCase().equals("note")) {
					appointment.setTaskcont(field.getFieldValues().get(0));
				} else if (field.getFieldName().toLowerCase()
						.equals("location")) {
					appointment.setLocation(field.getFieldValues().get(0));
				} else if (field.getFieldName().toLowerCase()
						.equals("startdate")) {
					appointment.setStartdate(field.getFieldValues().get(0));
				} else if (field.getFieldName().toLowerCase()
						.equals("starttime")) {
					appointment.setStarttime(field.getFieldValues().get(0));
				} else if (field.getFieldName().toLowerCase().equals("enddate")) {
					appointment.setEnddate(field.getFieldValues().get(0));
				} else if (field.getFieldName().toLowerCase().equals("endtime")) {
					appointment.setEndtime(field.getFieldValues().get(0));
				} else if (field.getFieldName().toLowerCase().equals("alarms")) {
					appointment.setAlarms(field.getFieldValues().get(0));
				} else if (field.getFieldName().toLowerCase().equals("minutes")) {
					appointment.setAlarmtime(field.getFieldValues().get(0));
				}
			}
			if (SystemConfig.stringIsNullOrEmpty(appointment.getSubject())) {
				continue;
			}
			if (SystemConfig.stringIsNullOrEmpty(appointment.getStartdate())) {
				continue;
			}
			if (SystemConfig.stringIsNullOrEmpty(appointment.getEnddate())) {
				continue;
			}

			// /////////////////

			ContentValues event = new ContentValues();
			event.put("title", appointment.getSubject());
			event.put("description", appointment.getTaskcont());

			event.put("calendar_id", calId);

			Date dtstart;
			if (!SystemConfig.stringIsNullOrEmpty(appointment.getStarttime())) {
				dtstart = datetimeSdf.parse(appointment.getStartdate() + " "
						+ appointment.getStarttime());
			} else {
				dtstart = datetimeSdf.parse(appointment.getStartdate());
			}
			long start = dtstart.getTime();
			Date dtend;
			if (!SystemConfig.stringIsNullOrEmpty(appointment.getEndtime())) {
				dtend = datetimeSdf.parse(appointment.getEnddate() + " "
						+ appointment.getEndtime());
			} else {
				dtend = datetimeSdf.parse(appointment.getEnddate());
			}
			long end = dtend.getTime();

			event.put("dtstart", start);
			event.put("dtend", end);
			event.put("eventLocation", appointment.getLocation());
			Long recordID = isAppointmentExist(appointment.getSubject(),
					appointment.getStartdate());
			if (recordID == -1) {
				if (!SystemConfig.stringIsNullOrEmpty(appointment.getAlarms())
						&& appointment.getAlarms().equals("1")) {
					event.put("hasAlarm", 1);

					Uri newEvent = baseView.getBaseActivity()
							.getContentResolver()
							.insert(Uri.parse(calanderEventURL), event);
					long id = Long.parseLong(newEvent.getLastPathSegment());
					ContentValues values = new ContentValues();
					values.put("event_id", id);
					if (SystemConfig.isNumberic(appointment.getAlarmtime())) {
						values.put("minutes",
								Integer.parseInt(appointment.getAlarmtime()));
						baseView.getBaseActivity().getContentResolver()
								.insert(Uri.parse(calanderReminderURL), values);
					}
				} else {
					event.put("hasAlarm", 0);

					baseView.getBaseActivity().getContentResolver()
							.insert(Uri.parse(calanderEventURL), event);
				}
			} else {
				if (!SystemConfig.stringIsNullOrEmpty(appointment.getAlarms())
						&& appointment.getAlarms().equals("1")) {
					event.put("hasAlarm", 1);

					Cursor reminderCursor = baseView
							.getBaseActivity()
							.getContentResolver()
							.query(Uri.parse(calanderReminderURL),
									new String[] { "event_id", "method",
											"minutes" }, "event_id=?",
									new String[] { String.valueOf(recordID) },
									null);
					if (reminderCursor.getCount() > 0) {
						ContentValues values = new ContentValues();
						if (SystemConfig.isNumberic(appointment.getAlarmtime())) {
							values.put("minutes", Integer.parseInt(appointment
									.getAlarmtime()));
						}
						baseView.getBaseActivity()
								.getContentResolver()
								.update(Uri.parse(calanderReminderURL),
										values,
										"event_id=?",
										new String[] { String.valueOf(recordID) });
					} else {
						ContentValues values = new ContentValues();
						values.put("event_id", recordID);
						if (SystemConfig.isNumberic(appointment.getAlarmtime())) {
							values.put("minutes", Integer.parseInt(appointment
									.getAlarmtime()));
							baseView.getBaseActivity()
									.getContentResolver()
									.insert(Uri.parse(calanderReminderURL),
											values);
						}
					}
					reminderCursor.close();
				} else {
					event.put("hasAlarm", 0);
				}
				Uri eventUri = ContentUris.withAppendedId(
						Uri.parse(calanderEventURL), recordID);
				baseView.getBaseActivity().getContentResolver()
						.update(eventUri, event, null, null);
			}
		}
	}

	public Long isAppointmentExist(String title, String startdate) {
		if (SystemConfig.stringIsNullOrEmpty(title)
				|| SystemConfig.stringIsNullOrEmpty(startdate))
			return -1l;
		for (int i = 0; i < scheduleList.size(); i++) {
			if (scheduleList.get(i).getSubject().equals(title)
					&& scheduleList.get(i).getStartdate().equals(startdate)) {
				return scheduleList.get(i).getRecordId();
			}
		}
		return -1l;
	}

	public List<String> getFuncType(String funcType) {
		String[] types = funcType.split("\"");
		List<String> resultType = new ArrayList<String>();
		for (int i = 1; i < types.length; i += 2) {
			resultType.add(types[i]);
		}
		return resultType;
	}
}
